package com.pan.common.interview.jvm;

/**
 * @author by panstark
 * @description
 * @notice
 * @date 2020/12/24
 */
public class JvmInfo {

    /**
     * JVM虚拟的计算机
     * 有着完整的计算机模块，classLoader 、runtime Data Area、Excution Engine、Native Interface
     */

    /**
     * jstack(查看线程)、jmap(查看内存)和jstat(性能分析)命令
     */

    /**
     * 加载class文件过程
     * 1、Class Loader：依据特定格式，加载class文件到内存
     * 2、Excution Engine：对命令进行解析
     * 3、native Interface：融合不同开发语言的原生库为java所用，即用来调用不同library。
     * 4、Runtime Dataarea：jvm内存空间结构模型
     */

    /**
     * 编译器将Robot.java源文件编译为Robot.class字节码文件
     * ClassLoader将字节码转换为JVM中的Class<Robot>对象
     * JVM利用Class<Robot>对象实例化为Robot对象
     */

    /**
     * jvm三大调优参数 -Xms -Xmx -Xss
     * 1、 -Xss:规定了每个线程虚拟机栈（堆栈）的大小，一般情况256K足够了，影响线程并发数的大小
     * 2、 -Xms：堆的初始值
     * 3、 -Xmx：堆能达到的最大值
     * 一般Xms与Xmx设置为相同大小，否则系统自动扩容会导致内存抖动，系统不稳定。
     *
     */

    /**
     * JVM的运行模式有两种
     * 1、Server（启动慢，优化多）
     * 2、client（启动快）
     */

    /**
     *
     * java中的Reference类型
     *
     * 问题
     *
     * 假设在一个应用中，需要从一个名为test的数据库表中获取数据。但凡有点经验的开发人员都会避免应用获取相同的数据每次都去查询数据库，因为I/O操作过去频繁势必会降低应用性能。
     *
     * 显然，我们首先想到的就是使用缓存。应用首先查询缓存，如果需要的数据存在直接拿来用就好；如果缓存未命中，才去数据库查询，并且把查询到的数据放入缓存，以便下次应用发起相同请求时可以直接从缓存获取数据而不用再次去数据库查询。
     *
     * 使用缓存会提高性能吗？
     *
     * 答案是这需要根据具体情况分析，如果从test获取需要缓存的数据量较少，使用缓存会非常合适且一定会提升性能。但假若需要从test表查询放到缓存里的数据量非常大，那就会出现一个问题：由于数据量过大可能会导致内存不足，而不单单是提升性能了。假如说把表中所有数据都放入缓存，那么缓存的可能会占据大部分jvm的内存或者索性直接产生一个OOM错误。
     *
     * 解决方案
     *
     * 最佳的方案是如果我们可以创造一种可以按需扩展和收缩的动态缓存，当我们的数据量需要而内存充裕的时候可以适当增加，但内存不足是可以按不同方案对其进行回收。
     *
     * 目的
     *
     * 这里引出的一个问题，就是为什么要在Java中使用不同类型的reference？我们的应用在运行过程中会产生很多对象，这些对象驻留在内存中，它们大小不同，重要性不同，使用频率不同，生命周期不同，比如有些对象只要应用启动就一直存活直到应用停止，而有些对象生命周期与创建它的线程相同，还有些对象只作临时变量短时间就消亡，再比如某些缓存数据，内存充裕的时候可以存活，内存不足的时候可能需要被首先牺牲被回收，所以很容易想象对于不同的对象，我们希望对他们的创建销毁采取不同的策略，可是不幸的是java不像C一样可以由开发者决定对象的析构销毁，而是将管理内存的活统一交给了jvm进行gc，但jvm显然不知道这些对象的区别。于是设计者们在java 1.2加入了reference，使jvm可以对不同的reference对象采取不同的回收策略以达到提高应用性能的目的。
     */


}
